﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Diagnostics;
using System.Windows.Forms;
using AFSharedLibrary.SharedControls;
using SharedClasses;
using UIDesigner.FieldHandlers;
using System.ComponentModel;
using DDW;
using System.Collections;
using System.Drawing;
using AFSharedLibrary;

namespace UIDesigner.FieldHandlers.Bases
{
    [DebuggerDisplay("{Info}")]
    public class FieldSpecification
    {
        private MemberNode m_objMember;
        private ParamDeclNode m_objParm;
        private ConstructedTypeNode m_objConstruct;
        private SortedDictionary<float, IFieldHandler> m_rgHandlers;
        private ControlOption m_objSelectedOption;
        private ControlOption m_objLastSelectedOption;
        private IComponent m_ctrlParent;
        private int m_nTabIndex = 0;
        private LayoutStyle m_eLayoutStyle;
        private Control m_ctrlBoundControl;
        private Size m_szControl;

        public ParamDeclNode Parm
        {
            get 
            { 
                return m_objParm; 
            }
            
            set 
            { 
                m_objParm = value; 
            }
        }

        public Size ControlSize
        {
            get 
            { 
                return m_szControl; 
            }
            
            set 
            { 
                m_szControl = value; 
            }
        }

        public Control BoundControl
        {
            get 
            { 
                return m_ctrlBoundControl; 
            }
            
            set 
            { 
                m_ctrlBoundControl = value; 
            }
        }

        public int TabIndex
        {
            get 
            { 
                return m_nTabIndex; 
            }
            
            set 
            { 
                m_nTabIndex = value; 
            }
        }

        public LayoutStyle LayoutStyle
        {
            get 
            { 
                return m_eLayoutStyle; 
            }
            
            set 
            { 
                m_eLayoutStyle = value; 
            }
        }

        public FieldSpecification(IComponent ctrlParent, ConstructedTypeNode objConstruct, ParmItem objParmItem, SortedDictionary<float, IFieldHandler> rgHandlers)
        {
            m_objConstruct = objConstruct;
            m_objMember = objParmItem.MatchingProperty;
            m_objParm = objParmItem.Parm;
            m_rgHandlers = rgHandlers;
            m_ctrlParent = ctrlParent;

            foreach (IFieldHandler objHandler in m_rgHandlers.Values)
            {
                foreach (string strOption in objHandler.GetControlOptions(ctrlParent, m_objMember))
                {
                    ControlOption objOption = new ControlOption(this, objHandler, strOption);
                    m_objSelectedOption = objOption;
                    m_objLastSelectedOption = m_objSelectedOption;

                    break;
                }

                break;
            }
        }

        public FieldSpecification(IComponent ctrlParent, ConstructedTypeNode objConstruct, MemberNode objMember, SortedDictionary<float, IFieldHandler> rgHandlers)
        {
            m_objConstruct = objConstruct;
            m_objMember = objMember;
            m_rgHandlers = rgHandlers;
            m_ctrlParent = ctrlParent;

            foreach (IFieldHandler objHandler in m_rgHandlers.Values)
            {
                foreach (string strOption in objHandler.GetControlOptions(ctrlParent, m_objMember))
                {
                    ControlOption objOption = new ControlOption(this, objHandler, strOption);
                    m_objSelectedOption = objOption;
                    m_objLastSelectedOption = m_objSelectedOption; 

                    break;
                }

                break;
            }
        }

        public void ClearSelection()
        {
            m_objLastSelectedOption = null;
        }

        public void Revert()
        {
            if (m_objLastSelectedOption != null)
            {
                m_objSelectedOption = m_objLastSelectedOption;
                m_objLastSelectedOption = null;
            }
        }

        public ControlOption SelectedOption
        {
            get 
            {
                return m_objSelectedOption; 
            }
            
            set 
            {
                m_objLastSelectedOption = m_objSelectedOption;
                m_objSelectedOption = value;
            }
        }

        public List<ControlOption> ControlOptions
        {
            get
            {
                SortedDictionary<string, ControlOption> rgOptions = new SortedDictionary<string, ControlOption>();
                List<ControlOption> rgList = new List<ControlOption>();

                foreach (IFieldHandler objHandler in m_rgHandlers.Values)
                {
                    foreach (string strOption in objHandler.GetControlOptions(m_ctrlParent, m_objMember))
                    {
                        if (!rgOptions.ContainsKey(strOption))
                        {
                            ControlOption objOption = new ControlOption(this, objHandler, strOption);
                            rgOptions.Add(strOption, objOption);
                        }
                    }
                }

                foreach (ControlOption objOption in rgOptions.Values)
                {
                    rgList.Add(objOption);
                }

                return rgList;
            }
        }

        protected bool IsDefaultMember
        {
            get
            {
                foreach (AttributeNode objAttr in m_objConstruct.Attributes)
                {
                    if (objAttr.Name.GenericIdentifier == "DefaultProperty")
                    {
                        StringPrimitive objString = (StringPrimitive)objAttr.Arguments[0].Expression;

                        if (objString.Value == m_objMember.Names[0].GenericIdentifier)
                        {
                            return true;
                        }
                    }
                }

                return false;
            }
        }

        protected bool HasGetter
        {
            get
            {
                PropertyNode objProperty = m_objMember as PropertyNode;
                InterfacePropertyNode objIProperty = m_objMember as InterfacePropertyNode;
                FieldNode objField = m_objMember as FieldNode;

                if (objProperty != null)
                {
                    return objProperty.Getter != null;
                }
                else if (objIProperty != null)
                {
                    return objIProperty.HasGetter;
                }
                else if (objField != null)
                {
                    return true;
                }

                return false;
            }
        }

        protected bool HasSetter
        {
            get
            {
                PropertyNode objProperty = m_objMember as PropertyNode;
                InterfacePropertyNode objIProperty = m_objMember as InterfacePropertyNode;
                FieldNode objField = m_objMember as FieldNode;

                if (objProperty != null)
                {
                    return objProperty.Setter != null;
                }
                else if (objIProperty != null)
                {
                    return objIProperty.HasSetter;
                }
                else if (objField != null)
                {
                    return true;
                }

                return false;
            }
        }

        public string MemberName
        {
            get
            {
                return m_objMember.Names[0].GenericIdentifier;
            }
        }

        public MemberNode Member
        {
            get
            {
                return m_objMember; 
            }
        }

        public string PrettyName
        {
            get
            {
                foreach (AttributeNode objAttr in m_objMember.Attributes)
                {
                    if (objAttr.Name.GenericIdentifier == "PrettyName")
                    {
                        StringPrimitive objString = (StringPrimitive)objAttr.Arguments[0].Expression;

                        return objString.Value;
                    }
                }

                return this.MemberName;
            }
        }

        public bool ReadOnlyResult
        {
            get
            {
                foreach (AttributeNode objAttr in m_objMember.Attributes)
                {
                    if (objAttr.Name.GenericIdentifier == "ReadOnlyResult")
                    {
                        BooleanPrimitive objBool = (BooleanPrimitive)objAttr.Arguments[0].Expression;

                        return objBool.Value;
                    }
                }

                return false;
            }
        }

        public bool WriteOnlyResult
        {
            get
            {
                foreach (AttributeNode objAttr in m_objMember.Attributes)
                {
                    if (objAttr.Name.GenericIdentifier == "WriteOnlyResult")
                    {
                        BooleanPrimitive objBool = (BooleanPrimitive)objAttr.Arguments[0].Expression;

                        return objBool.Value;
                    }
                }

                return false;
            }
        }

        public string PrettyDescription
        {
            get
            {
                foreach (AttributeNode objAttr in m_objMember.Attributes)
                {
                    if (objAttr.Name.GenericIdentifier == "PrettyName")
                    {
                        if (objAttr.Arguments.Count > 1)
                        {
                            StringPrimitive objString = (StringPrimitive)objAttr.Arguments[1].Expression;

                            return objString.Value;
                        }
                    }
                }

                return this.MemberName;
            }
        }

        public string Info
        {
            get
            {
                return this.MemberName + " (" + m_rgHandlers.Count.ToString() + ")"; 
            }
        }
    }
}
